/**
 * @(#)Task.java        1.0 2/15/12
 * 
 * Copyright (c) 2012 public static droid main
 * Georgia Institute of Technology, Atlanta, GA
 * All rights reserved.
 */

package edu.gatech.oad.publicstaticdroidmain.taskmanager.model;

import java.io.Serializable;
import java.util.Date;

/**
 * A single todo item that has a unique id, name, description, due date, 
 * location (represented with latitude and longitude values), frequency
 * of recurrence, and completion status.
 * 
 * @version 1.0 Feb 15 2012
 * @author Raheel Merali
 */
public class Task implements Serializable{
    /* This class is a simple information holder.  It only contains
     * getters and setters. */
    
    /* Used to denote how frequently a Task occurs */
    public static enum Recurrence { ONCE, DAILY, WEEKLY, MONTHLY, YEARLY };
    
    /* Used by other classes to reference a Task's attributes.  For example,
     * the TaskList class has a to2DArray() method that takes these attributes
     * as parameters and returns a 2D array with the rows representing the
     * Tasks in the list and the columns representing the specified attributes. */
    public static enum TaskAttribute { CATEGORY, ID, NAME, DESCRIPTION, DUE_DATE, 
        LATITUDE, LONGITUDE, RECURRENCE, COMPLETION_STATUS };
    
    /* Used to denote that a Task has no assigned latitude or longitude */
    public static final double NO_LOCATION = Double.MAX_VALUE;
    
    private static final String NO_LATITUDE_ASSIGNED_MESSAGE = "No latitute assigned";
    private static final String NO_LONGITUDE_ASSIGNED_MESSAGE = "No longitude assigned";
    
    private long id;
    private String name;
    private String description;
    private Date dueDate;
    private double latitude;
    private double longitude;
    private Recurrence recurrence;
    private boolean completed;
    private boolean selected;
    
    /**
     * Constructor a new Task with the specified attributes.
     * 
     * @param name the Task's name
     * @param description the Task's description
     * @param dueDate when the Task is due
     * @param latitude the latitude of the location where the Task is due
     * @param longitude the longitude of the location where the Task is due
     * @param recurrence how frequently the Task occurs
     */
    public Task(String name, String description, Date dueDate, double latitude, 
                double longitude, Recurrence recurrence) {
        this.id = System.currentTimeMillis();
        
        this.name = name;
        this.description = description;
        this.dueDate = dueDate;
        this.latitude = latitude;
        this.longitude = longitude;
        this.recurrence = recurrence;
        this.completed = false;
    }
    
    /**
     * Returns this Task's unique ID.
     *
     * @return this Task's unique ID.
     */
    public long getId() {
        return id;
    }
    
    /**
     * Returns this Task's name.
     *
     * @return this Task's name.
     */
    public String getName() {
        return name;
    }
    
    /**
     * Returns this Task's description.
     *
     * @return this Task's description
     */
    public String getDescription() {
        return description;
    }
    
    /**
     * Returns this Task's due date
     *
     * @return this Task's due date
     */
    public Date getDueDate() {
        return dueDate;
    }
    
    /**
     * Returns the latitude of the location where this Task is due.
     *
     * @return the latitude of the location where this Task is due
     */
    public double getLatitude() {
        return latitude;
    }
    
    /**
     * Returns the longitude of the location where this Task is due.
     *
     * @return the longitude of the location where this Task is due
     */
    public double getLongitude() {
        return longitude;
    }
    
    /**
     * Returns how frequently this Task occurs.
     *
     * @return how frequently this Task occurs.
     */
    public Recurrence getRecurrence() {
        return recurrence;
    }
    
    /**
     * Returns true if this Task is completed; false otherwise.
     *
     * @return true if this Task is completed; false otherwise.
     */
    public boolean isCompleted() {
	return completed;
    }
    
    /**
     * Sets this Task's unique ID to the specified ID.
     *
     * @param id the new unique ID
     */
    public void setId(long id) {
        this.id = id;
    }
    
    /**
     * Sets this Task's name to the specified name.
     *
     * @param name the new name
     */
    public void setName(String name) {
        this.name = name;
    }
    
    /**
     * Sets this Task's description to the specified description.
     *
     * @param description the new description
     */
    public void setDescription(String description) {
        this.description = description;
    }
    
    /**
     * Sets this Task's due date to the specified date.
     *
     * @param dueDate the new due date
     */
    public void setDueDate(Date dueDate) {
        this.dueDate = dueDate;
    }
    
    /**
     * Sets the latitude of the location where this Task is due to the
     * specified value.
     *
     * @param latitude the new latitude
     */
    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }
    
    /**
     * Sets the longitude of the location where this Task is due to the
     * specified value.
     *
     * @param longitude the new longitude
     */
    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }
    
    /**
     * Sets the frequency with which this Task occurs to the specified
     * recurrence.
     *
     * @param recurrence the new frequency
     */
    public void setRecurrence(Recurrence recurrence) {
        this.recurrence = recurrence;
    }
    
    /**
     * Sets this Task's completion status to the specified value.
     *
     * @param completed the new completion status
     */
    public void setCompleted(boolean completed) {
	this.completed = completed;
    }
    
    /**
     * Determines whether the specified object is equal to this Task.  Two
     * Tasks are equal if they are both Task objects with the same name, 
     * description, due date, latitude, longitude, and recurrence.
     *
     * @param other the object to be compared for equality with this Task
     * @return true if the specified object is equal to this Task; false otherwise
     */
    public boolean equals(Object otherObject) {
        if (otherObject == null) {
            return false;
        }
        
        if (this.getClass() != otherObject.getClass()) {
            return false;
        }
        
        Task otherTask = (Task)otherObject;
        
        if (!this.name.equals(otherTask.name)) {
            return false;
        }
        
        if (!this.description.equals(otherTask.description)) {
            return false;
        }
        
        if (!this.dueDate.equals(otherTask.dueDate)) {
            return false;
        }
        
        if (this.latitude != otherTask.latitude) {
            return false;
        }
        
        if (this.longitude != otherTask.longitude) {
            return false;
        }
        
        if (!this.recurrence.equals(otherTask.recurrence)) {
            return false;
        }
        
        return true;
    }
    
    /**
     * Generates a String representation of this Task of the form:
     * "ID: ...
     * Name: ...
     * Description: ...
     * Due Date: ...
     * Latitude: ...
     * Longitude: ...
     * Recurrence: ..."
     * 
     * If the latitude is equal to NO_LOCATION, "No assigned latitude"
     * is printed for the Task's latitude.  The same is true for longitude.
     *
     * @return a String representation of this Task
     */
    public String toString() {
    	return name;
//        StringBuffer stringRep = new StringBuffer();
//        
//        String latitudeString = "";
//        String longitudeString = "";
//        
//        if (latitude == NO_LOCATION) {
//            latitudeString = NO_LATITUDE_ASSIGNED_MESSAGE;
//        } else {
//            latitudeString = "" + latitude;
//        }
//        
//        if (longitude == NO_LOCATION) {
//            longitudeString = NO_LONGITUDE_ASSIGNED_MESSAGE;
//        } else {
//            longitudeString = "" + longitude;
//        }
//        
//        stringRep.append("ID: " + id + "\n");
//        stringRep.append("Name: " + name + "\n");
//        stringRep.append("Description: " + description + "\n");
//        stringRep.append("Due Date: " + dueDate.toString() + "\n");
//        stringRep.append("Latitude: " + latitudeString + "\n");
//        stringRep.append("Longitude: " + longitudeString + "\n");
//        stringRep.append("Recurrence: " + recurrence.toString());
//        
//        return stringRep.toString();
    }
    
    /**
     * Tests the methods in this class.
     * 
     * @param args not used
     */
    public static void main(String[] args) {
	int numTasks = 5;
	
	long ct = System.currentTimeMillis();
	
	String[] names = {"Do laundry", "Do homework", "Take shower", "Eat", "Sleep"};
	String[] descriptions = {"Don't forget to use soap",
				"Math is hard",
				"Use lots of soap",
				"Go to McDonald's",
				"Set alarm for 5AM" };
	
	
	Date[] dueDates = {new Date(ct + 5000), 
				new Date(ct + 6000), 
				new Date(ct + 90000), 
				new Date(ct + 1), 
				new Date(ct)};
        
	double[] latitudes = { NO_LOCATION, 23.5, 4, 77, 12 };
	double[] longitudes = { NO_LOCATION, 1, 2, 3, 4};
	Recurrence[] recurrences = { Recurrence.WEEKLY, Recurrence.DAILY, Recurrence.YEARLY, Recurrence.DAILY, Recurrence.DAILY };
        
	Task[] tasks = new Task[numTasks];
	
	for (int i = 0; i < numTasks; i++) {
	    tasks[i] = new Task(names[i], descriptions[i], dueDates[i], latitudes[i], longitudes[i], recurrences[i]);
	}
        
	System.out.println("toString() test:\n------------\n");
	for (Task t : tasks) {
	    System.out.println(t);
	    System.out.println();
	}
	
	System.out.println();
	
	System.out.println("equals() test 1:\n------------\n");
	for (int i = 0; i < numTasks; i++) {
	    System.out.println(tasks[i].equals(tasks[numTasks - i - 1]));
	}
	
	System.out.println();
	
	System.out.println("equals() test 2:\n------------\n");
	for (Task t : tasks) {
	    System.out.println(t.equals(t));
	}
	
	System.out.println();
    }

	public boolean isSelected() {
		return selected;
	}

	public void setSelected(boolean selected) {
		this.selected = selected;
	}

}